// SPDX-FileCopyrightText: 2023-2025 Sangfor Technologies Inc.
// SPDX-License-Identifier: Mulan PSL v2
package com.geniusai.aip.auth.controller;

import com.github.pagehelper.PageHelper;
import com.geniusai.aip.auth.domain.ChangePasswordEntity;
import com.geniusai.aip.auth.domain.EditEntity;
import com.geniusai.aip.auth.domain.Resource;
import com.geniusai.aip.auth.domain.ResponseTokenDTO;
import com.geniusai.aip.auth.domain.TotalResource;
import com.geniusai.aip.auth.domain.UserDO;
import com.geniusai.aip.auth.domain.UserProfile;
import com.geniusai.aip.auth.domain.UserVO;
import com.geniusai.aip.auth.domain.UsersVO;
import com.geniusai.aip.auth.domain.VGpuInfoVO;
import com.geniusai.aip.auth.domain.VGpuMemoryRemainVO;
import com.geniusai.aip.auth.domain.ResourceUsageTrendVO;
import com.geniusai.aip.auth.service.LoginService;
import com.geniusai.aip.auth.service.UserService;
import com.geniusai.aip.feature.common.web.Response;
import com.geniusai.aip.feature.common.web.common.PageModel;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.net.URISyntaxException;
import java.util.List;

/**
 * @author hml14563
 * @date 2021/3/18
 */

@RestController
@Slf4j
@RequestMapping("/v1")
public class UserController {
    @Autowired
    private LoginService loginService;

    @Autowired
    private UserService userService;

    @ApiOperation(value = "创建用户", httpMethod = "POST", notes = "创建用户", produces = "application/json")
    @PostMapping("/user")
    public Response<List<UserVO>> createUsers(@RequestBody UsersVO usersVO) {
        return Response.forSuccessWithData(userService.createUsers(usersVO));
    }

    @ApiOperation(value = "创建eds用户", httpMethod = "POST", notes = "创建eds用户", produces = "application/json")
    @PostMapping("/user/eds")
    public Response<UserDO> createEdsUserBucket(@RequestBody UserDO userDO) {
        return Response.forSuccessWithData(userService.createEdsUserBucket(userDO));
    }

    @ApiOperation(value = "删除eds用户", httpMethod = "DELETE", notes = "删除eds用户", produces = "application/json")
    @DeleteMapping("/user/eds/{userId}")
    public Response deleteEdsUser(@PathVariable String userId) {
        userService.deleteEdsUser(userId);
        return Response.forSuccess("删除用户成功");
    }

    @ApiOperation(value = "删除用户", httpMethod = "DELETE", notes = "删除用户", produces = "application/json")
    @DeleteMapping("/user/{userId}")
    public Response deleteUser(@PathVariable String userId) {
        userService.deleteUser(userId);
        return Response.forSuccess("删除用户成功");
    }

    @ApiOperation(value = "查看用户", httpMethod = "GET", notes = "查看用户", produces = "application/json")
    @GetMapping("/user")
    public Response<PageModel<UserVO>> getUser(
            @ApiParam(value = "keyword", example = "keyword") @RequestParam String keyword,
            @ApiParam(value = "页面数", example = "1") @RequestParam(defaultValue = "1") Integer pageNum,
            @ApiParam(value = "页面大小", example = "20") @RequestParam(defaultValue = "50") Integer pageSize
    ) {
        pageNum += 1;
        PageHelper.startPage(pageNum, pageSize);
        PageModel<UserVO> users = userService.getUser(keyword);
        return Response.forSuccessWithData(users);
    }

    @ApiOperation(value = "编辑用户信息", httpMethod = "PUT", notes = "编辑用户信息", produces = "application/json")
    @PutMapping("/user/{userId}")
    public Response<UserVO> editUser(@PathVariable String userId, @RequestBody EditEntity editEntity) {
        UserVO user = userService.editUser(userId, editEntity);
        return Response.forSuccessWithData(user);
    }

    @ApiOperation(value = "自己修改密码", httpMethod = "PUT", notes = "修改密码", produces = "application/json")
    @PutMapping("/user/{userId}/secret")
    public Response changePassword(
            HttpServletRequest request, HttpSession session,
            @Valid @RequestBody ChangePasswordEntity changePasswordEntity,
            @PathVariable String userId
    ) {
        userService.changePassword(changePasswordEntity, userId);
        loginService.logout(request, session);
        return Response.forSuccess("修改密码成功");
    }

    @ApiOperation(value = "查看资源", httpMethod = "GET", notes = "查看资源", produces = "application/json")
    @GetMapping("/resource")
    public Response<TotalResource> getResource() {
        TotalResource resource = userService.getResource();
        return Response.forSuccessWithData(resource);
    }

    @ApiOperation(value = "查看首页用户资源", httpMethod = "GET", notes = "查看资源", produces = "application/json")
    @GetMapping("/user/{userId}/resource")
    public Response<Resource> getResource(
            @PathVariable String userId
    ) {
        Resource resource = userService.getResourceByUserId(userId);
        return Response.forSuccessWithData(resource);
    }

    @ApiOperation(value = "查看首页用户信息资源", httpMethod = "GET", notes = "查看用户信息资源", produces = "application/json")
    @GetMapping("/user/{userId}/profile")
    public Response<UserProfile> getProfile(
            @PathVariable String userId
    ) {
        UserProfile profile = userService.getProfileByUserId(userId);
        return Response.forSuccessWithData(profile);
    }

    @ApiOperation(value = "获取用户登陆信息", httpMethod = "GET", notes = "获取用户登陆信息", produces = "application/json")
    @GetMapping("/user/loginInfo")
    public Response<ResponseTokenDTO> getLoginInfo(HttpServletRequest request) {
        ResponseTokenDTO loginInfo = userService.getLoginInfo(request);
        return Response.forSuccessWithData(loginInfo);
    }

    @ApiOperation(value = "获取系统vGpu信息", httpMethod = "GET", notes = "获取系统vGpu信息", produces = "application/json")
    @GetMapping("/vGpuInfo")
    public Response<VGpuInfoVO> getVGpuInfo() {
        VGpuInfoVO vGpuInfoVO = userService.getVGpuInfo();
        return Response.forSuccessWithData(vGpuInfoVO);
    }

    @ApiOperation(value = "获取用户vGpu算力使用率趋势图", httpMethod = "GET", notes = "获取用户vGpu算力使用率趋势图", produces = "application/json")
    @GetMapping("/user/{userId}/vGpuRatioUsageTrend")
    public Response<ResourceUsageTrendVO> getVGpuRatioUsageTrend(@PathVariable String userId, String timeCode) {
        ResourceUsageTrendVO vGpuRatioUsageTrendVO = userService.getVGpuRatioUsageTrend(userId, timeCode);
        return Response.forSuccessWithData(vGpuRatioUsageTrendVO);
    }

    @ApiOperation(value = "获取用户vGpu显存占用率趋势图", httpMethod = "GET", notes = "获取用户vGpu显存占用率趋势图", produces = "application/json")
    @GetMapping("/user/{userId}/vGpuMemoryUsageTrend")
    public Response<ResourceUsageTrendVO> getVGpuMemoryUsageTrend(@PathVariable String userId, String timeCode) throws URISyntaxException {
        ResourceUsageTrendVO vGpuMemoryUsageTrendVO = userService.getVGpuMemoryUsageTrend(userId, timeCode);
        return Response.forSuccessWithData(vGpuMemoryUsageTrendVO);
    }

    @ApiOperation(value = "查询用户剩余可用显存和vGpu", httpMethod = "GET", notes = "查询用户剩余可用显存和vGpu", produces = "application/json")
    @GetMapping("/user/{userId}/vGpuMemoryRemain")
    public Response<VGpuMemoryRemainVO> getVGpuMemoryRemain(@PathVariable String userId) {
        VGpuMemoryRemainVO vGpuMemoryUsageTrendVO = userService.getVGpuMemoryRemain(userId);
        return Response.forSuccessWithData(vGpuMemoryUsageTrendVO);
    }

    @ApiOperation(value = "资源占用趋势图", httpMethod = "POST", notes = "资源占用趋势图", produces = "application/json")
    @GetMapping("/user/resourceUsingGraph")
    public Response<ResourceUsageTrendVO> getResourceUsingGraph(String timeCode, String trendChartType) {
        ResourceUsageTrendVO resourceUsingGraph = userService.getResourceUsingGraph(timeCode, trendChartType);
        return Response.forSuccessWithData(resourceUsingGraph);
    }
}
